<?php
/**
 * @desc config class file
 * @author nana
 * @date 2011
 * @usage
 *      $config = NICED_Config::getInstance();
 *      $config->init();
 *
 */
class NICED_Config extends NICED_Container 
{
	protected static $instance;
	
	public static function getInstance() 
	{
		if (!isset(self::$instance) || !is_object(self::$instance)) 
		{
			self::$instance = new NICED_Config();
		}

		return self::$instance;
	}

	public function __construct() 
	{
		//self::loadConfig();//load config
	}

	public static function init()
	{
		self::loadConfig();
	}
	
	
	/**
	 * @desc load all config from config files
	 * @return void
	 * 
	 */
	public static function loadConfig() 
	{
		//load config from file
		$app_config_dir = DIR_CONFIG;//config path

		if (is_dir($app_config_dir)) 
		{
			if ($dh = opendir($app_config_dir)) 
			{
				while (($filename = readdir($dh)) !== false) //loop all config files
				{ 
					if ('.' == $filename || '..' == $filename || '.' == substr($filename, 0, 1)) 
					{
						continue;
					}

					$filename = strtolower($filename);
					$type = basename($filename, '.php');
					require_once($app_config_dir.$filename);//include file

					switch ($type) 
					{
						case 'board_config' : //board_config
						{ 
							SC::set($type, $cfg);
							break;
						}
						case 'router' : //app router
						{ 
							//foreach ($cfg as $key => $value) 
							//{
							//	LC::set($type.'.'.$key, strtolower($value));
							//}
							foreach ($cfg as $key => $value) 
							{
                                $cfg[$key] = strtolower($value);
							}
							SC::set($type, $cfg);
							
							break;
						}
						case 'server': 
						{
							LC::set($type, $cfg);
							//NICED_DBFactory::setConfig($type, $cfg);
							break;
						}
						case 'dsn': 
						{
							LC::set($type, $cfg);
							//NICED_DBFactory::setConfig($type, $cfg);
							break;
						}
						case 'dao': 
						{
							LC::set($type, $cfg);
							//NICED_DaoFactory::setDaoConfig($cfg);	
							break;
						}
						case 'application' : //application config for app
						{ 
							LC::set($type, $cfg);
							break;
						}
                        case "apps" :
                        case "database" :
                        {

							LC::set($type, $cfg);
							break;							
                        }
						default: 
						{
							//LC::set($type, $cfg);
							break;							
						}
					}			
				}

				closedir($dh);

				//if (!NICED_DBFactory::$populated) 
				//{
				//	NICED_DBFactory::resolve();
				//}
			}
		} //end load config from file


        $niced_log_level = SC::get("board_config.niced_log_level");
        $niced_log_level = "DEBUG";
        NICED_LOG($niced_log_level, SC::getAllData(), NICED." config from file: ");

        $load_from_db = SC::get("board_config.load_from_db");
        NICED_LOG($niced_log_level, "load from db ".(int)$load_from_db);

        //board config from db
        if ($load_from_db)
        {
            $rows = self::getBoarConfigFromDB();
            NICED_LOG($niced_log_level, $rows, NICED." boardconfig from db: ");
            if ($rows)
            {
                self::mergeBoardConfigToSC($rows);
            }
        }

        //local config from db
        if ($load_from_db)
        {
            $rows = self::getLocalConfigFromDB();
            NICED_LOG($niced_log_level, $rows, NICED." localconfig from db: ");
            if ($rows)
            {
                self::mergeLocalConfigToLC($rows);
            }
        }

        NICED_LOG($niced_log_level, SC::getAllData(), NICED." config final: ");

        return true;
    }

    private static function getBoarConfigFromDB()
    {
        $mem_key = "board_config_from_db";

        if (SC::get("board_config.cache.enable"))
        {
            $cacher = MemcacheFactory::create('query_memcache');
            $rows = $cacher->get($mem_key);
            if ($rows)
            {
                return $rows;
            }
        }

        $rows = array();
        $dao = NICED_DaoFactory::create("system.board_config");
        $dao->appendWhere(1);
        $rs = $dao->execute();

        if (!$rs->isSuccess())
        {
            throw new NICED_Exception("load board config from db fail");
        }

        $rows = array();
        while ($row = $rs->fetchRow())
        {
            $rows[] = $row;
        }

        if ($rows && isset($cacher))
        {
            $cacher->set($mem_key, $rows, MEMCACHE_COMPRESSED, SC::get("board_config.cache.expire"));
        }

        return $rows;
    }

    private static function mergeBoardConfigToSC($rows)
    {
        foreach ($rows as $row)
        {
            SC::set("board_config.".$row["field"], $row["value"]); 
        } 
    }

    private static function getLocalConfigFromDB()
    {
        $mem_key = "local_config_from_db";

        if (SC::get("board_config.cache.enable"))
        {
            $cacher = MemcacheFactory::create('query_memcache');
            $rows = $cacher->get($mem_key);
            if ($rows)
            {
                return $rows;
            }
        }

        $rows = array();
        $dao = NICED_DaoFactory::create("system.local_config");
        $dao->appendWhere(1);
        $rs = $dao->execute();

        if (!$rs->isSuccess())
        {
            throw new NICED_Exception("load local config from db fail");
        }

        $rows = array();
        while ($row = $rs->fetchRow())
        {
            $rows[] = $row;
        }

        if ($rows && isset($cacher))
        {
            $cacher->set($mem_key, $rows, MEMCACHE_COMPRESSED, SC::get("board_config.cache.expire"));
        }

        return $rows;
    }


    private static function mergeLocalConfigToLC($rows)
    {
        $apps_from_db = array();
        foreach ($rows as $row)
        {
            if ("apps" != $row["type"])
            {
                $key = $row["type"].".".$row["field"];
                LC::set($key, $row["value"]); 
            }
            else
            {
                $apps_from_db[$row["field"]] = $row["value"];
            }
        } 

        if ($apps_from_db)
        {
            $apps  = LC::get("apps");
            $apps  = array_merge($apps, $apps_from_db);
            LC::set("apps", $apps);
        }
    }

} //end class
